package com.zenithsun.common.util.image;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.drew.imaging.ImageMetadataReader;
import com.drew.imaging.ImageProcessingException;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.Tag;

/**
 * 图片信息类，用于校验图片的合法性，获取图片的基础属性<br/>
 * 校验图片的合法性：checkImage() 获取图片的基础属性：loadImgInfo()
 * 
 * @author wanglei@enersun.com.cn
 */
public class ImageInfo {

	public Date getShootDateTime() {
		return shootDateTime;
	}

	public void setShootDateTime(Date shootDateTime) {
		this.shootDateTime = shootDateTime;
	}
	private File file;
	private ImageCheck imageCheck;

	public ImageInfo(){
		
	}
	
	public ImageInfo(String fileName) {
		file = new File(fileName);
	}
	public ImageInfo(File nfile) {
		file = nfile;
	}
	/**
	 * 图片高度
	 */
	private String imgHeight;

	/**
	 * 图片宽度
	 */
	private String imgWidth;

	/**
	 * 拍摄时间
	 */
	private String dateTime;
	
	/**
	 * 拍摄时间
	 */
	private Date shootDateTime;

	/**
	 * 文件大小
	 */
	private Long imgSize;

	/**
	 * 文件名称
	 */
	private String imgName;

	/**
	 * 拍摄者
	 */
	private String artist;

	/**
	 * 版权
	 */
	private String copyright;

	/**
	 * 文件类型
	 */
	private String mimeType;

	/**
	 * 描述
	 */
	private String remark;
	
	
	public String getRemark() {
		return remark;
	}
	public void setRemark(String remark) {
		this.remark = remark;
	}
	public String getMimeType() {
		return mimeType;
	}

	public void setMimeType(String mimeType) {
		this.mimeType = mimeType;
	}

	public String getArtist() {
		return artist;
	}

	public void setArtist(String artist) {
		this.artist = artist;
	}

	public String getCopyright() {
		return copyright;
	}

	public void setCopyright(String copyright) {
		this.copyright = copyright;
	}

	public String toString() {
		return "[图片信息]文件名称：" + this.imgName + "   拍摄者：" + this.artist
				+ "   版权所有：" + this.copyright + "   文件大小：" + this.imgSize
				+ "  高度：" + this.imgHeight + "  宽度：" + this.imgWidth
				+ "  拍摄时间：" + this.dateTime;
	}

	public String getImgHeight() {
		return imgHeight;
	}

	public void setImgHeight(String imgHeight) {
		this.imgHeight = imgHeight;
	}

	public String getImgWidth() {
		return imgWidth;
	}

	public void setImgWidth(String imgWidth) {
		this.imgWidth = imgWidth;
	}

	public String getDateTime() {
		return dateTime;
	}

	public void setDateTime(String dateTime) {
		this.dateTime = dateTime;
		this.shootDateTime=this.GetImageDate(this.dateTime);
	}

	public Long getImgSize() {
		return imgSize;
	}

	public void setImgSize(Long imgSize) {
		this.imgSize = imgSize;
	}

	public String getImgName() {
		return imgName;
	}

	public void setImgName(String imgName) {
		this.imgName = imgName;
	}

	/**
	 * 图片信息获取metadata元数据信息，该方法执行后，可以直接获取属性
	 * @return boolean
	 * @throws ImageProcessingException
	 * @throws IOException
	 */
	public boolean loadImgInfo() throws ImageProcessingException, IOException {
		boolean flag = false;
		if (file.exists()) {
			Metadata metadata = ImageMetadataReader.readMetadata(file);
			loadImageTags(file, metadata);
			this.setArtist(getPhotographerByRex(this.remark));
			this.setRemark(this.getRemark().replace(this.getArtist(), ""));
			this.setArtist(getPhotographerReplace(this.getArtist()));
			flag = true;
		}
		return flag;
	}

	/**
	 * 图片信息获取metadata元数据信息，该方法执行后，可以直接获取属性
	 * @return boolean
	 * @throws ImageProcessingException
	 * @throws IOException
	 */
	public boolean loadImgInfo(byte[] bytes) throws ImageProcessingException, IOException {
		boolean flag = false;
		try {
			if (bytes!=null&&bytes.length>0) {
				System.setProperty("javax.xml.parsers.DocumentBuilderFactory","com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
				Metadata metadata = ImageMetadataReader.readMetadata(new ByteArrayInputStream(bytes));
				loadImageTags(metadata);
				this.setArtist(getPhotographerByRex(this.remark));
				if(this.getArtist()!=null){
					this.setRemark(this.getRemark().replace(this.getArtist(), ""));
					this.setArtist(getPhotographerReplace(this.getArtist()));
				}
				flag = true;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return flag;
	}
	
	/**
	 * 去除摄影者姓名中多余的信息
	 * @param find
	 * @return
	 */
	private static String getPhotographerReplace(String find) {
		if (find != null) {
			find = find.replace("。", "");
			find = find.replace("（", "");
			find = find.replace("）", "");
			find = find.replace("( ", "");
			find = find.replace(") ", "");
			find = find.replace("摄", "");
			//find = find.replace("图", "");
			return find.trim();
		}
		return null;
	}
	
	/**
	 * 根据正则表达式获取摄影者
	 * @param timeStr
	 * @return
	 */
	private static String getPhotographerByRex(String str) {
		String[] regs = { "。[\\w\\W]+摄","。[\\w\\W]+图","。[\\w\\W]+拍", "（[\\w\\W]+摄）", "([\\w\\W]+摄)" ,"（[\\w\\W]+）"," [\\w\\W]+摄"}; 
		for (String reg : regs) {
			Pattern pattern = Pattern.compile(reg);
			Matcher matcher = pattern.matcher(str);
			while (matcher.find()) {
				return matcher.group();
			}
		}
		return null;
	}
	 
	/**
	 * 判断文件是否正确
	 * 
	 * @return boolean
	 * @throws Exception
	 */
	public boolean checkImage() throws Exception {
		boolean flag = false;
		if (file.exists()) {
			imageCheck = new ImageCheck();
			imageCheck.setInput(new FileInputStream(file));
			flag = imageCheck.check();
			this.mimeType = imageCheck.getMimeType();
		}
		return flag;
	}

	/**
	 * 读取metadata里面的信息，并将信息存入到属性中
	 * 
	 * @param sourceFile
	 *            源文件
	 * @param metadata
	 *            metadata元数据信息
	 */
	private void loadImageTags(File sourceFile, Metadata metadata) {
		this.setImgSize(sourceFile.getTotalSpace());
		this.setImgName(sourceFile.getName());
		for (Directory directory : metadata.getDirectories()) {
			for (Tag tag : directory.getTags()) {
				String tagName = tag.getTagName();
				String desc = tag.getDescription();
				if (tagName.indexOf("Image Height") >= 0) {
					// 图片高度
					this.setImgHeight(desc);
				} else if (tagName.indexOf("Image Width") >= 0) {
					// 图片宽度
					this.setImgWidth(desc);
				} else if (tagName.indexOf("Date/Time Original") >= 0) {
					// 拍摄时间
					this.setDateTime(desc);
				} else if (tagName.indexOf("Artist") >= 0) {
					// 拍摄者
					this.setArtist(desc);
				} else if (tagName.indexOf("Copyright") >= 0) {
					// 版权
					this.setCopyright(desc);
				}
			}
			for (String error : directory.getErrors()) {
				System.err.println("ERROR: " + error);
			}
		}
	}
	
	/**
	 * 读取metadata里面的信息，并将信息存入到属性中
	 * 
	 * @param sourceFile
	 *            源文件
	 * @param metadata
	 *            metadata元数据信息
	 */
	private void loadImageTags(Metadata metadata) {
		for (Directory directory : metadata.getDirectories()) {
			for (Tag tag : directory.getTags()) {
				String tagName = tag.getTagName();
				String desc = tag.getDescription();
				if (tagName.indexOf("Image Height") >= 0) {
					// 图片高度
					this.setImgHeight(desc);
				} else if (tagName.indexOf("Image Width") >= 0) {
					// 图片宽度
					this.setImgWidth(desc);
				} else if (tagName.indexOf("Date/Time Original") >= 0) {
					// 拍摄时间
					this.setDateTime(desc);
				} else if (tagName.indexOf("Artist") >= 0) {
					// 拍摄者
					this.setArtist(desc);
				} else if (tagName.indexOf("Copyright") >= 0) {
					// 版权
					this.setCopyright(desc);
				}
			}
			for (String error : directory.getErrors()) {
				System.err.println("ERROR: " + error);
			}
		}
	}
	
	  /**
     * 获取yyyy:MM:dd HH:mm:ss格式的时间
     * @param date
     * @return
     */
    private Date GetImageDate(String date){
    	SimpleDateFormat formatter = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
    	if(date.indexOf("CST")>0){ 
    		formatter = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
    	}
    	try {
			return formatter.parse(date);
		} catch (ParseException e) {
			e.printStackTrace();
		}
    	return null;
    }
}
